<template>
	<div class="app-container">
		<!-- 搜索条件 -->
		<yd-form class="yd-form-wraper" :model="formData" :options="formOptions">
			<template #form-btn>
				<el-form-item label="部门">
					<treeselect
						v-model="formData.deptId"
						:options="dsScopeData"
						placeholder="选择部门"
						:objMap="{
							label: 'name',
							value: 'id',
							children: 'children',
						}"
					/>
				</el-form-item>
				<el-button type="primary" @click="handleSearch">查询</el-button>
			</template>
		</yd-form>
		<YdTable
			:formData="formData"
			:tableConfig="tableConfig"
			:tableData="tableData"
			@sizeChangeHandler="handleSearch"
			@currentChangeHandler="getData"
			@sortChangeHandler="getData"
			@selectionChangeHandler="handleSelectionChange"
		>
		</YdTable>
		<!-- 添加或修改对话框 -->
		<el-dialog
			v-model="addFormDialog.open"
			:title="addFormDialog.title"
			width="500px"
			append-to-body
			center
			:close-on-click-modal="false"
			@close="cancelHandle"
		>
			<yd-form ref="dialogForm" class="yd-form-wraper" :model="dialogFormData" :options="dialogFormOptions">
				<template #form-footer>
					<!-- <el-checkbox v-model="showPassword" label="修改密码"></el-checkbox>
					<el-form-item label="旧密码" prop></el-form-item> -->

					<div class="dialog-footer">
						<el-button v-if="addFormDialog.showSubmit" type="primary" :disabled="addFormDialog.disableSubmit" @click="submitDialogForm"
							>确 定</el-button
						>
						<el-button v-if="addFormDialog.showSubmit" @click="cancelHandle">取 消</el-button>
					</div>
				</template>
			</yd-form>
			<template #footer>
				<!-- <el-button v-if="addFormDialog.showClose" type="primary" @click="cancelHandle">关 闭</el-button> -->
			</template>
		</el-dialog>

		<!-- 导入弹出层 -->
		<el-dialog v-model="importDialog.open" title="用户信息导入" width="500px" :close-on-click-modal="false" center>
			<div style="text-align: center">
				<el-upload
					ref="uploadRef"
					:headers="importDialog.headers"
					action="/admin/user/import"
					drag
					:auto-upload="false"
					accept=".xls,.xlsx"
					:limit="1"
					:before-upload="handleBeforeUpload"
					:on-success="handlerUploadOnSuccess"
					:on-error="handlerUploadOnError"
				>
					<el-icon><Upload /></el-icon>
					<div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
				</el-upload>
				<div style="text-align: left">*只能上传.xls、.xlsx文件</div>
			</div>
			<template #footer>
				<div class="dialog-footer">
					<el-button type="primary" @click="downloadTemplate">下载模板</el-button>
					<el-button type="primary" @click="handlerImport">确 定</el-button>
					<el-button @click="importDialog.open = false">取 消</el-button>
				</div>
			</template>
		</el-dialog>

		<!-- <el-dialog v-model="dialogPermissionVisible" :close-on-click-modal="false" title="分配权限">
			<div class="dialog-main-tree">
				<el-tree
					ref="menuTree"
					:data="treeData"
					:default-checked-keys="checkedKeys"
					:check-strictly="false"
					:props="defaultProps"
					:filter-node-method="filterNode"
					class="filter-tree"
					node-key="id"
					highlight-current
					show-checkbox
					default-expand-all
				/>
			</div>
			<template #footer>
				<div class="dialog-footer">
					<el-button type="primary" size="small" @click="updatePermession(roleId)">更 新 </el-button>
					<el-button type="default" size="small" @click="cancal()">取消 </el-button>
				</div>
			</template>
		</el-dialog> -->
	</div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, nextTick, watch } from 'vue';
import { addObj, delObj, fetchList, putObj, getDetails, fetchUserTemplate } from '@/api/admin/user';
import { deptRoleList } from '@/api/admin/role';
import { fetchTree } from '@/api/admin/dept';
import { listPosts } from '@/api/admin/post';
import useCurrentInstance from '@/utils/useCurrentInstance';
import { validatorKey } from '@/utils/validate';
import request from '@/utils/request';
import { downloadFromBlob } from '@/utils/common';
import { Local } from '@/utils/storage';
import useUserStore from '@/store/modules/userinfo';
import Treeselect from '@/components/TreeSelect/index.vue';
const { proxy } = useCurrentInstance();

let validateUsername = (rule: any, value: any, callback: any) => {
	if (dialogFormData.userId) callback();
	let flag = new RegExp(/^([a-z\u4e00-\u9fa5\d]+?)$/).test(value);
	if (!flag) {
		callback(new Error('用户名支持小写英文、数字、中文'));
	}

	getDetails(value).then((response) => {
		const result = response.data ?? null;
		if (result !== null) {
			callback(new Error('用户名已经存在'));
		} else {
			callback();
		}
	});
};

const dialogForm = ref();
const scopeTree = ref();
const uploadRef = ref();
const menuTree = ref();

const formData = reactive<FormModelType>({
	deptId: '',
});

// 表单项配置
const formOptions = ref<FormOptionType>([
	{
		type: 'input',
		label: '用户名称',
		prop: 'username',
	},
]);

const tableConfig = reactive<TableConfigType>({
	columns: [
		{
			label: '用户名',
			prop: 'username',
			width: 180,
		},
		{
			label: '姓名',
			prop: 'name',
		},
		{
			label: '手机号',
			prop: 'phone',
		},
		{
			label: '岗位',
			prop: 'postList',
			render(row: any, val: any[]) {
				let str = '';
				val.forEach((item: any) => {
					str += `<span class="yd-table-btn">${item.postName}</span>`;
				});
				return str;
			},
		},
		{
			label: '角色',
			prop: 'roleList',
			width: 300,
			render(row: any, val: any[]) {
				let str = '';
				val.forEach((item: any) => {
					str += `<span class="yd-table-btn">${item.roleName}</span>`;
				});
				return str;
			},
		},
		{
			label: '状态',
			prop: 'lockFlag',
			formatter(row: any, val: string) {
				if (val === '9') {
					return '已锁定';
				}
				return '正常';
			},
		},
		{
			label: '创建时间',
			prop: 'createTime',
		},
	],
	// 工具栏
	toolBar: [
		{ name: '新增', icon: 'yd-icon-plus', permi: ['sys_user_add'], handler: () => addHandle() },
		{ name: '修改', icon: 'yd-icon-edit', permi: ['sys_user_edit'], disable: 'single', handler: () => updateHandle() },
		{ name: '删除', icon: 'yd-icon-delete', permi: ['sys_user_del'], disable: 'multiple', handler: () => deleteHandle() },
		{ name: '导入', icon: 'yd-icon-delete', handler: () => handlerImport() },
		{ name: '导出', icon: 'yd-icon-delete', handler: () => exportExcel() },
	],
	// 开启复选框
	enableSelection: true,
	pagination: {
		pageNum: 1,
	},
	loading: false,
});
// 选中数组
const ids = ref([]);
// 非单个禁用
const single = ref(true);
// 非多个禁用
const multiple = ref(true);

const tableData = ref<any[]>();

const dialogPermissionVisible = ref(false);

const dsScopeData = ref<any[]>();
const treeData = ref<any[]>();
const checkedDsScope = ref<any[]>();
const checkedKeys = ref<any[]>();

const roleId = ref();
const roleCode = ref();

const menuIds = ref();

const showPassword = ref(true);

const defaultProps = {
	label: 'name',
	value: 'id',
};
// 新增、修改弹窗配置
const addFormDialog = reactive({
	open: false,
	title: '',
	showSubmit: true,
	roleCodeDisable: false,
	disableSubmit: false, //禁止提交
});

// 新增、修改表单
const dialogFormData = reactive<FormModelType>({
	changePassword: false,
});

const dialogFormOptions = ref<FormOptionType>([
	{
		type: 'input',
		label: '用户名',
		prop: 'username',
		span: 24,
		attrs: {
			disabled: false,
		},
		rules: [
			{
				required: true,
				message: '请输入用户名',
			},
			{
				min: 3,
				max: 20,
				message: '长度在 3 到 20 个字符',
				trigger: 'blur',
			},
			{ validator: validateUsername, trigger: 'blur' },
		],
	},
	{
		type: 'input',
		label: '密码',
		prop: 'password',
		span: 24,
		show: true,
		attrs: {
			type: 'password',
			showPassword: true,
		},
		rules: [
			{
				min: 6,
				max: 20,
				required: true,
				message: '长度在 6 到 20 个字符',
				trigger: 'blur',
			},
		],
	},

	{
		type: 'input',
		label: '姓名',
		prop: 'name',
		span: 24,
		rules: [
			{
				min: 2,
				max: 64,
				required: true,
				message: '请输入姓名',
				trigger: 'blur',
			},
		],
	},
	{
		type: 'input',
		label: '手机号',
		prop: 'phone',
		span: 24,
		rules: [
			{
				min: 11,
				max: 11,
				required: true,
				message: '长度在 11 个字符',
				trigger: 'blur',
			},
		],
	},
	{
		type: 'group-select',
		label: '所属部门',
		prop: 'deptId',
		span: 24,
		isInitValue: false,
		selectKey: 'id',
		selectLabel: 'name',
		api: {
			name: 'queryDeptTree',
		},
		rules: [
			{
				required: true,
				message: '请选择部门',
				trigger: 'change',
			},
		],
	},
	{
		type: 'select',
		label: '岗位',
		prop: 'post',
		span: 24,
		isInitValue: false,
		selectKey: 'postId',
		selectLabel: 'postName',
		api: {
			name: 'queryPostList',
		},
		attrs: {
			multiple: true,
		},
		rules: [
			{
				required: true,
				message: '请选择岗位',
				trigger: 'blur',
			},
		],
	},
	{
		type: 'select',
		label: '角色',
		prop: 'role',
		span: 24,
		isInitValue: false,
		selectKey: 'roleId',
		selectLabel: 'roleName',
		api: {
			name: 'queryRoleList',
		},
		attrs: {
			multiple: true,
		},
		rules: [
			{
				required: true,
				message: '请选择角色',
				trigger: 'blur',
			},
		],
	},
	{
		type: 'radio-group',
		label: '状态',
		prop: 'lockFlag',
		span: 24,
		rules: [
			{
				required: true,
				message: '请选择状态',
				trigger: 'blur',
			},
		],
		children: [
			{
				label: '有效',
				value: '0',
			},
			{
				label: '锁定',
				value: '9',
			},
		],
	},
	{
		type: 'input',
		label: '昵称',
		prop: 'nickname',
		span: 24,
		rules: [
			{
				min: 1,
				max: 64,
				message: '请输入昵称',
				trigger: 'blur',
			},
		],
	},
	{
		type: 'input',
		label: '邮箱',
		prop: 'email',
		span: 24,
		rules: [
			{
				min: 4,
				max: 128,
				message: '请输入邮箱',
				trigger: 'blur',
			},
		],
	},
	{
		type: 'checkbox',
		label: '',
		prop: 'changePassword',
		span: 24,
		show: false,
		style: {
			marginLeft: '50px',
		},
		children: [
			{
				label: '修改密码:',
				value: '0',
			},
		],
	},
	{
		type: 'input',
		label: '旧密码',
		prop: 'password',
		span: 24,
		showCascader: {
			prop: 'changePassword',
			showValue: true,
		},
		attrs: {
			type: 'password',
			showPassword: true,
		},
		rules: [
			{
				min: 6,
				max: 20,
				required: true,
				message: '长度在 6 到 20 个字符',
				trigger: 'blur',
			},
		],
	},
	{
		type: 'input',
		label: '新密码',
		prop: 'newpassword1',
		span: 24,
		showCascader: {
			prop: 'changePassword',
			showValue: true,
		},
		attrs: {
			type: 'password',
			showPassword: true,
		},
		rules: [
			{
				min: 6,
				max: 20,
				required: true,
				message: '长度在 6 到 20 个字符',
				trigger: 'blur',
			},
		],
	},
]);
const tenantId = useUserStore().userInfo.tenantId;
const importDialog = reactive({
	open: false,
	// 上传请求头
	headers: {
		Authorization: 'Bearer ' + Local.get('access_token'),
		'TENANT-ID': tenantId ? tenantId : '1',
		VERSION: 'dengfazhu',
	},
});

watch(
	() => dialogFormData.changePassword,
	(val) => {
		console.log('formData.changePassword', dialogFormData.changePassword);
	},
	{
		deep: true,
	}
);

onMounted(() => {
	queryDeptData();
	handleSearch();
});

function handleSearch() {
	tableConfig.pagination!.pageNum = 1;
	getData();
}

function getData() {
	tableConfig.loading = true;
	console.log('formDAta', formData);
	let params = {
		...formData,
		current: formData.pageNum,
		size: formData.pageSize,
		descs: formData.orderByColumn,
	};
	fetchList(params)
		.then((res: ApiResponse) => {
			tableData.value = res.data.records;
			tableConfig.pagination!.total = res.data.total;
			tableConfig.loading = false;
		})
		.catch(() => {
			tableConfig.loading = false;
		});
}

// 多选框选中数据
function handleSelectionChange(selection: any) {
	ids.value = selection.map((item: anyObj) => item.userId);
	single.value = selection.length !== 1;
	multiple.value = !selection.length;
}

function queryDeptData(show?: any, type?: any) {
	// window.boxType = type;
	fetchTree().then((res: ApiResponse) => {
		if (res.code === 0) {
			dsScopeData.value = res.data;
			if (dialogFormData.dsScope) {
				checkedDsScope.value = dialogFormData.dsScope.split(',');
			} else {
				checkedDsScope.value = [];
			}
		}
	});
	// // 查询角色列表
	// deptRoleList().then((response) => {
	// 	this.rolesOptions = response.data.data;
	// });
	// // 查询岗位列表
	// listPosts().then((response) => {
	// 	this.postOptions = response.data.data;
	// });
	// if (['edit', 'view'].includes(type)) {
	// 	this.role = [];
	// 	for (let i = 0; i < this.form.roleList.length; i++) {
	// 		this.role[i] = this.form.roleList[i].roleId;
	// 	}
	// 	this.post = [];
	// 	for (let i = 0; i < this.form.postList.length; i++) {
	// 		this.post[i] = this.form.postList[i].postId;
	// 	}
	// } else if (type === 'add') {
	// 	this.role = [];
	// 	this.post = [];
	// 	this.form.username = undefined;
	// 	this.form.phone = undefined;
	// 	this.form.password = undefined;
	// }

	// show();
}

/** 新增按钮操作 */
function addHandle() {
	reset();
	dialogFormOptions.value[1].show = true;
	let option = dialogFormOptions.value.find((opt: any) => opt.prop === 'changePassword');
	option!.show = false;
	dialogFormData.changePassword = false;
	addFormDialog.title = '增加用户';
	addFormDialog.open = true;
	//控制是否可以有提交按钮，详情不能有提交按钮
	addFormDialog.showSubmit = true;
	// addFormDialog.showClose = false;
	(dialogFormOptions.value[0].attrs as any).disabled = false;
}
/** 修改按钮操作 */
function updateHandle() {
	reset();
	dialogFormOptions.value[1].show = false;
	let option = dialogFormOptions.value.find((opt: any) => opt.prop === 'changePassword');
	option!.show = true;
	// dialogFormData.changePassword = true;
	addFormDialog.title = '修改用户';
	addFormDialog.open = true;
	//控制是否可以有提交按钮，详情不能有提交按钮
	addFormDialog.showSubmit = true;
	// addFormDialog.showClose = false;
	(dialogFormOptions.value[0].attrs as any).disabled = true;
	const id = ids.value[0];

	let obj = tableData.value?.find((item: any) => item.userId === id);

	if (obj) {
		if (obj.postList instanceof Array) {
			obj.post = obj.postList.map((item: any) => item.postId);
		}
		if (obj.roleList instanceof Array) {
			obj.role = obj.roleList.map((item: any) => item.roleId);
		}
		// 对密码转码
		obj.password = '';
		Object.assign(dialogFormData, obj);
	}
}
/** 删除按钮操作 */
function deleteHandle() {
	if (ids.value === null) {
		proxy.$modal.msgWarning('请选择要删除的用户信息。');
		return;
	}
	proxy.$modal
		.confirm('是否删除已经勾选的用户?', '警告', {
			confirmButtonText: '确定',
			cancelButtonText: '取消',
			cancelButtonClass: 'confirm-rigth-cancel-button',
			type: 'warning',
		})
		.then(function () {
			return delObj(ids.value);
		})
		.then((res: ApiResponse) => {
			if (res.code === 0) {
				getData();
				proxy.$modal.msgSuccess('删除成功');
			}
		});
}

function reset() {
	for (let key in dialogFormData) {
		if (key === 'changePassword') {
			dialogFormData[key] = false;
		} else {
			dialogFormData[key] = '';
		}

		// dialogFormData.dsType = 0;
	}

	// dialogForm

	dialogForm.value?.resetFields();
}

// 查看
function handleDetail() {}

// 修改
function handleUpdate() {}

// function cancal() {
// 	dialogPermissionVisible.value = false;
// }

// 查看
function getDetail(row: any) {}

/**
 * 解析出所有的太监节点id
 * @param json 待解析的json串
 * @param idArr 原始节点数组
 * @param temp 临时存放节点id的数组
 * @return 太监节点id数组
 */
function resolveAllEunuchNodeId(json: any, idArr: any, temp: any) {
	for (let i = 0; i < json.length; i++) {
		const item = json[i];
		// 存在子节点，递归遍历;不存在子节点，将json的id添加到临时数组中
		if (item.children && item.children.length !== 0) {
			resolveAllEunuchNodeId(item.children, idArr, temp);
		} else {
			temp.push(idArr.filter((id: any) => id === item.id));
		}
	}
	return temp;
}

// 新增修改确认按钮
function submitDialogForm() {
	console.log('dialogFormData.dsScope', dialogFormData);

	dialogForm.value?.validate((valid: boolean, _msg: any) => {
		console.log('_msg', valid);
		console.log('submitDialogForm', dialogFormData);
		if (valid) {
			if (dialogFormData.userId) {
				if (dialogFormData.changePassword !== true) {
					// 新增、或者修改不修改密码的时候，删除密码参数
					dialogFormData.changePassword !== undefined && delete dialogFormData.changePassword;
					dialogFormData.password !== undefined && delete dialogFormData.password;
					dialogFormData.newpassword1 !== undefined && delete dialogFormData.newpassword1;
				}
				update();
			} else {
				if (dialogFormData.changePassword !== true) {
					// 新增、或者修改不修改密码的时候，删除密码参数
					dialogFormData.changePassword !== undefined && delete dialogFormData.changePassword;
					dialogFormData.newpassword1 !== undefined && delete dialogFormData.newpassword1;
				}
				create();
			}
			addFormDialog.disableSubmit = true;
		}
	});
}

function create() {
	// if (dialogFormData.dsType === 1) {
	// 	dialogFormData.dsScope = scopeTree.value?.getCheckedKeys().join(',');
	console.log('create(', dialogFormData.dsScope);
	// }
	addObj(dialogFormData)
		.then((res: ApiResponse) => {
			if (res.code === 0) {
				getData();
				proxy.$modal.msgSuccess('创建成功');
				setTimeout(() => {
					addFormDialog.open = false;
					addFormDialog.disableSubmit = false;
				}, 100);
			}
		})
		.catch(() => {
			addFormDialog.disableSubmit = false;
		});
}
function update() {
	// if (formData.dsType === 1) {
	// 	formData.dsScope = scopeTree.value?.scopeTree.getCheckedKeys().join(',');
	// }
	console.log('update', dialogFormData);
	putObj(dialogFormData)
		.then((res: ApiResponse) => {
			if (res.code === 0) {
				getData();
				proxy.$modal.msgSuccess('修改成功');
				setTimeout(() => {
					addFormDialog.open = false;
					addFormDialog.disableSubmit = false;
				}, 1000);
			}
		})
		.catch(() => {
			addFormDialog.disableSubmit = false;
		});
}
// function updatePermession(roleId: any) {
// 	menuIds.value = '';
// 	menuIds.value = menuTree.value?.getCheckedKeys().join(',').concat(',').concat(menuTree.value?.getHalfCheckedKeys().join(','));
// 	permissionUpd(roleId, menuIds.value).then(() => {
// 		dialogPermissionVisible.value = false;
// 		proxy.$modal.msgSuccess('修改成功');
// 	});
// }

function filterNode(value: any, data: any) {
	if (!value) return true;
	return data.label.indexOf(value) !== -1;
}

function cancelHandle() {
	addFormDialog.open = false;
	reset();
}

function exportExcel() {
	downBlobFile('/admin/user/export', {}, 'user.xlsx');
}
function downBlobFile(url: string, query: any, fileName: string) {
	return request({
		url: url,
		method: 'get',
		responseType: 'blob',
		params: query,
	}).then((response: any) => {
		// 处理返回的文件流
		const blob = response;
		if (blob && blob.size === 0) {
			proxy.msgError('内容为空，无法下载');
			return;
		}
		const link = document.createElement('a');
		link.href = window.URL.createObjectURL(blob);
		link.download = fileName;
		document.body.appendChild(link);
		link.click();
		window.setTimeout(function () {
			window.URL.revokeObjectURL(blob);
			document.body.removeChild(link);
		}, 0);
	});
}

function handleBeforeUpload(file: any, a: any, c: any) {
	let ext = file.name?.split('.')[1];
	if (ext !== 'xls' && ext !== 'xlsx') {
		proxy.$modal.msgError('上传的文件格式不正确');
		return false;
	}
}

// 导入成功
function handlerUploadOnSuccess(res: any) {
	console.log('handlerUploadOnSuccess', res);

	if (res.code !== 0) {
		let msg;
		if (res.code === 1) {
			let data = res.data;
			if (data && data instanceof Array && data.length) {
				msg = data[0].errors ? '用户名已存在或者用户信息错误！' : '';
			}
			uploadRef.value?.clearFiles();
		}
		msg = msg || '导入失败';
		proxy.$modal.msgError(msg);
		return;
	}
	importDialog.open = false;
	getData();
	proxy.$modal.msgSuccess(res.msg);
	// uploadRef.value?.clearFiles();
}
// 导入失败
function handlerUploadOnError() {
	importDialog.open = false;
	proxy.$modal.msgError('导入失败');
}

// 下载导入模板
function downloadTemplate() {
	fetchUserTemplate('user.xlsx').then((res: ApiResponse) => {
		downloadFromBlob(res, '用户信息模板').then((o) => {
			if (!o.flag) {
				proxy.$modal.msgWarning(o.msg);
			}
		});
	});
}

/**
 * 导入
 */
function handlerImport() {
	// 判断窗口是否打开
	if (!importDialog.open) {
		importDialog.open = true;
		nextTick(() => {
			uploadRef.value?.clearFiles();
		});

		return;
	}
	uploadRef.value.submit();
}
</script>

<style>
.dialog-footer {
	display: flex;
	justify-content: center;
	margin-top: 20px;
	padding: 0 30px;
}
.dialog-main-tree {
	height: 500px;
	overflow: auto;
}
</style>
